"""
流式构建器 - 链式API消除样板代码
基于Linus设计哲学："好代码没有特殊情况"
"""

import asyncio
from typing import Any, AsyncGenerator, List, Tuple, Union, Optional
from .response import StreamResponse


class StreamBuilder:
    """流式构建器 - 链式API消除样板代码"""
    
    def __init__(self):
        self.operations: List[Tuple[str, Any, float]] = []
    
    def range(self, start: int, end: int, delay: float = 0):
        """添加数字范围操作"""
        self.operations.append(("range", (start, end), delay))
        return self
    
    def items(self, items: Any, delay: float = 0):
        """添加项目列表操作"""
        self.operations.append(("items", items, delay))
        return self
    
    def text(self, text: str, delay: float = 0):
        """添加文本字符操作"""
        self.operations.append(("text", text, delay))
        return self
    
    def json(self, data: Any, delay: float = 0):
        """添加JSON数据操作"""
        self.operations.append(("json", data, delay))
        return self
    
    def build(self, download=False, filename=None):
        """构建流式响应 - 实时流式生成"""
        # Linus式修复：检测是否有延迟操作，自动使用零缓冲确保延迟生效
        has_delay = any(delay > 0 for _, _, delay in self.operations)
        buffer_size = 0 if has_delay else 8192  # 有延迟时使用零缓冲，否则使用默认缓冲
        
        async def generator() -> AsyncGenerator[str, None]:
            for op_type, data, delay in self.operations:
                if op_type == "range":
                    start, end = data
                    for i in range(start, end):
                        yield f"data_{i}\n"
                        if delay > 0:
                            await asyncio.sleep(delay)
                        # 强制刷新，确保实时性
                        await asyncio.sleep(0)
                elif op_type == "items":
                    for item in data:
                        yield f"{item}\n"
                        if delay > 0:
                            await asyncio.sleep(delay)
                        # 强制刷新，确保实时性
                        await asyncio.sleep(0)
                elif op_type == "text":
                    for char in data:
                        yield char
                        if delay > 0:
                            await asyncio.sleep(delay)
                        # 强制刷新，确保实时性
                        await asyncio.sleep(0)
                elif op_type == "json":
                    from .json_utils import json_dumps
                    yield json_dumps(data) + "\n"
                    if delay > 0:
                        await asyncio.sleep(delay)
                    # 强制刷新，确保实时性
                    await asyncio.sleep(0)
        
        # 设置下载头部
        headers = None
        if download:
            headers = {"content-disposition": f"attachment; filename={filename or 'stream.txt'}"}
        
        return StreamResponse(generator(), headers=headers, buffer_size=buffer_size)


class SSEBuilder:
    """SSE构建器 - 消除SSE样板代码"""
    
    def __init__(self):
        self.events: List[dict] = []
    
    def start(self, data=None, event="message"):
        """添加开始事件"""
        if data is not None:
            # 直接使用传入的数据，避免不必要的嵌套
            if isinstance(data, dict):
                if "type" not in data:
                    event_data = {"type": "start", "data": data}
                else:
                    event_data = {"type": "start", "data": data}
            else:
                event_data = {"type": "start", "data": data}
        else:
            event_data = {"type": "start"}
        return self.event(event_data, event)
    
    def chunk(self, content, **meta):
        """添加数据块事件"""
        # 如果content已经是包含type的字典，直接使用
        if isinstance(content, dict) and "type" in content:
            event_data = {**content, **meta}
        else:
            # 合并content和meta到一个字典中
            if isinstance(content, dict):
                event_data = {"type": "chunk", **content, **meta}
            else:
                event_data = {"type": "chunk", "content": content, **meta}
        return self.event(event_data, "message")
    
    def end(self, message=None, **meta):
        """添加结束事件"""
        # 如果meta中已经包含type，直接使用
        if "type" in meta:
            event_data = meta
        else:
            event_data = {"type": "end", **meta}
            if message is not None:
                event_data["message"] = message
        return self.event(event_data, "message")
    
    def event(self, data: Union[dict, str], event: str = "message", id: Optional[str] = None):
        """添加自定义事件"""
        event_dict = {"event": event, "data": data}
        if id is not None:
            event_dict["id"] = id
        self.events.append(event_dict)
        return self
    
    def build(self):
        """构建SSE响应 - 实时流式生成，不缓存事件"""
        from .response import SSEResponse
        
        async def generator() -> AsyncGenerator[str, None]:
            # 实时生成每个事件，不预先缓存
            for event in self.events:
                # 立即格式化并发送事件，不等待
                event_str = ""
                if "event" in event:
                    event_str += f"event: {event['event']}\n"
                if "id" in event:
                    event_str += f"id: {event['id']}\n"
                
                data = event["data"]
                if isinstance(data, (dict, list)):
                    from .json_utils import json_dumps
                    data = json_dumps(data)
                else:
                    data = str(data)
                
                for line in data.split('\n'):
                    event_str += f"data: {line}\n"
                event_str += "\n"
                
                # 立即yield，确保实时性
                yield event_str
                
                # 强制刷新缓冲区，确保立即发送
                await asyncio.sleep(0)  # 让出控制权，确保事件立即发送
        
        return SSEResponse(generator())


# 便捷函数 - 一行创建流式响应
def stream():
    """创建流式构建器"""
    return StreamBuilder()


def sse():
    """创建SSE构建器"""
    return SSEBuilder()


# 常用快捷函数
def stream_range(start: int, end: int, delay: float = 0.5):
    """快速创建数字范围流"""
    return stream().range(start, end, delay).build()


def stream_items(items: Any, delay: float = 0):
    """快速创建项目列表流"""
    return stream().items(items, delay).build()


def stream_text(text: str, delay: float = 0.1):
    """快速创建文本字符流"""
    return stream().text(text, delay).build()


def sse_ping_stream(interval: float = 30.0, count: Optional[int] = None):
    """快速创建心跳SSE流"""
    
    async def ping_generator():
        i = 0
        while count is None or i < count:
            yield {"event": "heartbeat", "data": "ping"}
            await asyncio.sleep(interval)
            i += 1
    
    from .response import SSEResponse
    return SSEResponse(ping_generator())